#include "config.h"
#include "debug.h"
#include "app_config.h"

#include "STC32G_Timer.h"
#include "STC32G_GPIO.h"
#include "STC32G_NVIC.h"
#include "STC32G_Exti.h"
#include "STC32G_I2C.h"
#include "STC32G_Delay.h"
#include "STC32G_Switch.h"

#include "drv_ina3221.h"

#if TCFG_DRV_INA3221_SUPPORT
 
/**
*******************************************************************************
* @brief   设定采集的样本数量并一起取平均值
* @note  	-   0   : 1    (采样次数)
* @note  	-	1   : 4    (采样次数)
* @note  	-	2   : 16   (采样次数)
* @note  	-   3   : 64   (采样次数)
* @note  	-	4   : 128  (采样次数)
* @note  	-	5   : 256  (采样次数)
* @note  	-   6   : 512  (采样次数)
* @note  	-	7   : 1024 (采样次数)
*******************************************************************************
*/
uint8_t CFG_AVG      = 2;
/**
*******************************************************************************
* @brief   总线电压测量设定转换时间
* @note  	-   0   : 140us
* @note  	-	1   : 204us
* @note  	-	2   : 332us
* @note  	-   3   : 588us
* @note  	-	4   : 1.1ms
* @note  	-	5   : 2.116ms
* @note  	-   6   : 4.156ms
* @note  	-	7   : 8.244ms
*******************************************************************************
*/
uint8_t CFG_VbusCT   = 3;
/**
*******************************************************************************
* @brief   为分流电压测量设定转换时间
* @note  	-   0   : 140us
* @note  	-	1   : 204us
* @note  	-	2   : 332us
* @note  	-   3   : 588us
* @note  	-	4   : 1.1ms
* @note  	-	5   : 2.116ms
* @note  	-   6   : 4.156ms
* @note  	-	7   : 8.244ms
*******************************************************************************
*/
uint8_t CFG_VshCT    = 3;
/**
*******************************************************************************
* @brief   选择连续的、 触发的、 或者省电运行模式
* @note  	-   0   : 省电
* @note  	-	1   : 分流电压、触发模式
* @note  	-	2   : 总线电压、触发模式
* @note  	-   3   : 分流和总线电压、触发模式
* @note  	-	4   : 省电
* @note  	-	5   : 分流电压、持续模式
* @note  	-   6   : 总线电压、持续模式
* @note  	-	7   : 分流和总线电压、持续模式
*******************************************************************************
*/
uint8_t CFG_Mode     = 7;

 
void INA3221_SendData(uint8_t addr, uint8_t reg, uint16_t val)
{
    I2C_WriteNbyte(addr, reg, (u8*)&val, 2);
}


uint16_t INA3221_ReadData(uint8_t addr, u8 reg)
{
    u8 val[2];
    I2C_ReadNbyte(addr, reg, val, 2);
    return (uint16_t)(((u16)(val[0]) << 8) | val[1]); 
}

 
/**
 * @description: INA3221自检
 * @param {uint8_t} addr
 * @return {*}
 */
void INA3221_SelfCheck(uint8_t addr)
{
    uint16_t id = 0;
    while (id != INA3221_DIE_ID)
    {
//        delay_ms(50);
        //卡这说明硬件连接异常或者是地址错误
        id = INA3221_ReadData(addr, INA3221_DIEID_REG);
    }
}
 
/********************************应用部分****************************************/
 
/**
 * @description: 获取电压
 * @param {uint8_t} addr
 * @param {uint8_t} channel 通道编号(1\2\3)
 * @return {uint16_t} 通道所对应的电压
 */
static int32_t INA3221_GetVoltage(uint8_t addr, uint8_t channel)
{
    uint32_t temp = 0;
    uint16_t reg=0;
    switch (channel)
    {
    case 1:
        reg = INA3221_CH1BUS_REG;
        break;
    case 2:
        reg = INA3221_CH2BUS_REG;
        break;
    case 3:
        reg = INA3221_CH3BUS_REG;
        break;
    default:
        return 0;
    }

    temp = INA3221_ReadData(addr, reg);
    if (temp & 0x8000)
        temp = ~(temp - 1);
	
    return (uint16_t)temp;
}
 
 
/**
 * @description: 获取分流电压
 * @param {uint8_t} addr    ina3221的IIC地址
 * @param {uint8_t} channel 通道编号(1\2\3)
 * @return {uint16_t} 通道的分流电压
 */
static float INA3221_GetShuntVoltage(uint8_t addr, uint8_t channel)
{
    int16_t val_raw=0;
    uint8_t reg = 0;
    switch (channel)
    {
    case 1:
        reg = INA3221_CH1SHUNT_REG;
        break;
    case 2:
        reg = INA3221_CH2SHUNT_REG;
        break;
    case 3:
        reg = INA3221_CH3SHUNT_REG;
        break;
    default:
        return 0;
    }
    val_raw = (int16_t)INA3221_ReadData(addr, reg);

    // if (temp & 0x8000)
    //     temp = ~(temp - 1);

    return (float)(val_raw*0.04f);
}

 
//设置电压警告
static void Set_Voltage_Warning(uint8_t ch,uint16_t value)
{
	switch(ch)
	{
		case 1:INA3221_SendData(INA3221_ADDR1, INA3221_CH1WAL_REG, value); break;
		case 2:INA3221_SendData(INA3221_ADDR1, INA3221_CH2WAL_REG, value); break;
		case 3:INA3221_SendData(INA3221_ADDR1, INA3221_CH3WAL_REG, value); break;
		case 4:INA3221_SendData(INA3221_ADDR2, INA3221_CH1WAL_REG, value); break;
		case 5:INA3221_SendData(INA3221_ADDR2, INA3221_CH2WAL_REG, value); break;
		case 6:INA3221_SendData(INA3221_ADDR2, INA3221_CH3WAL_REG, value); break;
	}
}
 
//设置电压严重报警
static void Set_Voltage_Critical(uint8_t ch,uint16_t value)
{
	switch(ch)
	{
		case 1:INA3221_SendData(INA3221_ADDR1, INA3221_CH1CAL_REG, value); break;
		case 2:INA3221_SendData(INA3221_ADDR1, INA3221_CH2CAL_REG, value); break;
		case 3:INA3221_SendData(INA3221_ADDR1, INA3221_CH3CAL_REG, value); break;
		case 4:INA3221_SendData(INA3221_ADDR2, INA3221_CH1CAL_REG, value); break;
		case 5:INA3221_SendData(INA3221_ADDR2, INA3221_CH2CAL_REG, value); break;
		case 6:INA3221_SendData(INA3221_ADDR2, INA3221_CH3CAL_REG, value); break;
	}
}

//统一设置警告值
void Set_WARNING_CRITICAL(void)
{
	int i;
	float vcci[6] = {1600/1000.0,
	                 1200/1000.0,
	                 350/1000.0,
	                 350/1000.0,
	                 350/1000.0,
	                 350/1000.0};
	uint16_t vi = 0;
	for(i=0;i<6;i++)
	{
		vi= (uint16_t)(vcci[i]*25/0.04)<<3;
		Set_Voltage_Warning(i+1,vi);//过压保护
		Set_Voltage_Critical(i+1,vi);//过流保护
	}
}

/**
 * @description: INA3221初始化
 * @return {*}
 */
void INA3221_Init(void)
{	
	unsigned int cfg_reg_value = 0;
	//芯片初始化
    INA3221_SendData(INA3221_ADDR1, INA3221_CFG_REG, 0x8000); //软件复位
	INA3221_SendData(INA3221_ADDR2, INA3221_CFG_REG, 0x8000); //软件复位
    delay_ms(10);
    // 配置寄存器设置控制三个输入通道的分流和总线电压测量的工作模式。 
    // 该寄存器控制分流和总线电压测量的转换时间设置以及使用的平均模式。 
    // 配置寄存器用于独立启用或禁用每个通道，以及选择控制选择要测量的信号的操作模式。
    // 详见数据手册P26
	cfg_reg_value = 0x7000|(CFG_AVG<<9)|(CFG_VbusCT<<6)|(CFG_VshCT<<3)|CFG_Mode;
 
    INA3221_SendData(INA3221_ADDR1, INA3221_CFG_REG, cfg_reg_value); // 7127为默认配置
	INA3221_SendData(INA3221_ADDR2, INA3221_CFG_REG, cfg_reg_value); // 7127为默认配置
}


int32_t drv_ina3221_bus_voltage(uint8_t addr, uint8_t channel)
{
    return INA3221_GetVoltage(addr, channel);   
}

float drv_ina3221_shunt_voltage(uint8_t addr, uint8_t channel)
{
    return INA3221_GetShuntVoltage(addr, channel);
}

void ina3221_process(void)
{
    log_d("bus voltage:%d\n", drv_ina3221_bus_voltage(INA3221_I2C_ADDRESS, 1));
    log_d("shunt voltage:%f\n", drv_ina3221_shunt_voltage(INA3221_I2C_ADDRESS, 1));
}

void drv_ina3221_init(void)
{
    I2C_InitTypeDef i2c;
    i2c.I2C_Enable = ENABLE;
    i2c.I2C_Mode = I2C_Mode_Master;
    i2c.I2C_Speed = MAIN_Fosc/2/(100000*2+4);
    i2c.I2C_MS_WDTA = DISABLE;
    i2c.I2C_SL_MA = ENABLE;
    I2C_Init(&i2c);

    // NVIC_I2C_Init(I2C_Mode_Master, ENABLE, Priority_1);  // I2C Master模式可不用开中断

    P2_MODE_IO_PU(GPIO_Pin_4);
    P2_MODE_IO_PU(GPIO_Pin_5);

    I2C_SW(I2C_P24_P25);

    INA3221_Init();

    Set_WARNING_CRITICAL();

    log_d("INA3221 Driver Init\n");
}
#endif

